home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
libs
/
3dvect39
/
poly.inc
< prev
next >
Wrap
Text File
|
1994-10-30
|
59KB
|
1,865 lines
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;
; Filename : Poly.inc
; Included from: 3D1.ASM, 3D2.ASM, 3D3.ASM
; Description : 3D xmode, polyfill and object handling routines
;
; Written by: John McCarthy
; 1316 Redwood Lane
; Pickering, Ontario.
; Canada, Earth, Milky Way (for those out-of-towners)
; L1X 1C5
;
; Internet/Usenet: BRIAN.MCCARTHY@CANREM.COM
; Fidonet: Brian McCarthy 1:229/15
; RIME/Relaynet: ->CRS
;
; Home phone, (905) 831-1944, don't call at 2 am eh!
;
; John Mccarthy would really love to work for a company programming Robots
; or doing some high intensive CPU work. Hint. Hint.
;
; Send me your protected mode source code!
; Send me your Objects!
; But most of all, Send me a postcard!!!!
;
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
public _polyfill ; fill polygon
public _fakeline_horz ; draw line in memory buffer
public _fakeline_vert ; draw line in memory buffer (glenz)
public _set_clip_absolute ; set clipping parameters - absolute
public _set_clip_offset ; set clipping parameters - offset
public _fastimultable ; fast imul table, dw 0-319 * 200
public _clipped_line ; draw clipped line from dx,cx to ax,bx colour bp
public _sortlist ; sort vector list
public _drawvect ; draw vectors from command list
public _copy_virtual_objects ; copy real objects to virtual list
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;
; _polyfill: Draws a filled polygon given table left and right addresses
;
; In:
; Regs=none
;
; Memory - these get set up by _fakeline_horz routine
;
; _colq - colour for polygon
; _poly_oney - top of polygon in table (maps to y location of screen)
; _poly_firstbyte[] - left side to begin draw
; _poly_lastbyte[] - right side to end draw
; _current_page - current offset of video memory for page of xmode, see xmode.asm
;
; Out:
; null
;
; Notes:
; Call _fakeline_horz to define the edges of your polygon, then call here to fill it
;
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
align 4
pf_done:
pop eax
pf_outearly:
mov _poly_oney,1000 ; reset for next polygon call
ret
align 4
_polyfill:
; out_8 sc_index, map_mask ; set up for plane select
xor eax,eax
mov ebx,_poly_oney ; ax=_y1
cmp bx,_ymins
jl s pf_missub
cmp bx,_ymaxs
jge pf_outearly
sub bx,_ymins
mov ax,bx
pf_missub:
mov ebp,eax ; indexer to line
add ebp,ebp
add ax, _cliptp
mov edi, _current_page ; point to active vga page
mov eax,[eax*4+_fastimultable] ; mul _y1 by bytes per line
add edi,eax ; di = start of line _y1
xor edx,edx
pf_more_lines:
push edi ; save right hand position
mov ax, [_poly_firstbyte+ebp]
cmp ax,_xmaxs ; check if fill done
jge pf_done
xor ebx,ebx
mov bx,[_poly_lastbyte+ebp]
add ax,_xcent
add bx,_xcent
mov edx,eax ; dx = _x1 (pixel position)
shr edx,2 ; dx/4 = bytes into line
add edi,edx ; di = addr of upper-left corner
mov ecx,ebx ; cx = _x2 (pixel position)
shr ecx,2 ; cx/4 = bytes into line
cmp edx,ecx ; start and end in same band?
jg pf_exit ; skip if _fakeline_horz fails connection
je pf_one_band_only ; if so, then special processing
mov ah,_colq ; get fill color
sub ecx,edx ; cx = # bands -1
mov esi,eax ; si = plane#(_x1)
and esi,plane_bits ; if left edge is aligned then
jz s pf_l_plane_flush ; no special processing..
; draw "left edge" of 1-3 pixels...
out_8 sc_data, _left_clip_mask[esi] ; set left edge plane mask
mov [edi], ah ; fill in left edge pixels
inc edi ; point to middle (or right) block
dec ecx ; reset cx instead of jmp pf_right
pf_l_plane_flush:
inc ecx ; add in left band to middle block
; di = addr of 1st middle pixel (band) to fill
; cx = # of bands to fill -1
pf_right:
mov esi,ebx ; get xpos2
and esi,plane_bits ; get plane values
cmp esi,0003 ; plane = 3?
je s pf_r_edge_flush ; hey, add to middle
; draw "right edge" of 1-3 pixels...
out_8 sc_data, _right_clip_mask[esi] ; right edge plane mask
mov esi,edi ; get addr of left edge
add esi,ecx ; add width-1 (bands) to point to top of right edge
dec esi
pf_right_loop:
mov [esi], ah ; fill in right edge pixels
dec ecx ; minus 1 for middle bands
jz s pf_exit ; uh.. no middle bands...
pf_r_edge_flush:
; di = addr of upper left block to fill
; cx = # of bands to fill in (width)
out_8 sc_data, all_planes ; write to all planes
mov dx, xactual/4 ; dx = di increment
sub edx, ecx ; = _screen_width-# planes filled
mov al, ah ; colour is in high and low for stosw
pf_middle_loop:
shr ecx,1 ; dont use doubleword transfer
rep stosw
adc cl,0
rep stosb
pf_exit:
pop edi
mov d [_poly_firstbyte+ebp-2],03e803e8h ; reset table for next polygon (1000 doubleword)
mov d [_poly_lastbyte+ebp-2],0fc18fc18h ; -1000 doubleword
add ebp,2
add edi,xactual/4
jmp pf_more_lines
pf_one_band_only:
cmp ax, _cliplt
jne s pf_nexit
cmp bx,ax
je s pf_exit
pf_nexit:
cmp ax, _cliprt
je s pf_exit
mov esi,eax ; get left clip mask, save _x1
and esi,plane_bits ; mask out row #
mov al,_left_clip_mask[esi] ; get left edge mask
mov esi,ebx ; get right clip mask, save _x2
and esi,plane_bits ; mask out row #
and al,_right_clip_mask[esi] ; get right edge mask byte
out_8 sc_data, al ; clip for left & right masks
mov ah,_colq ; get fill color
mov [edi], ah ; fill in pixels
jmp s pf_exit ; outa here, for this line
align 4
ss_done:
pop eax
ss_outearly:
mov _poly_oney,1000 ; reset for next polygon call
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; SS_dosteel: Fill polygon with a sine-waved texture. Implemented by the use
; of the "wavey" texture option.
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
align 4
ss_dosteel:
; out_8 sc_index, map_mask ; set up for plane select
xor eax,eax
mov ebx,_poly_oney ; ax=_y1
cmp bx,_ymins
jl s ss_missub
cmp bx,_ymaxs
jge ss_outearly
sub bx,_ymins
mov ax,bx
ss_missub:
mov bl,_colq ; yes, save colour offset and 16 block
mov steelc,bl
and steelc,0f0h ; save base offset of 16 colour block
shl bl,2 ; colour offset is *2 (small) *4 (large)
add bl,al ; make steel always constant
sub ebx,_poly_oney ; ***** ; remove this line if you want sine textures to be "pegged" - eg stationary
and bl,03fh ; colour indexer (so sides look different)
mov steel ,bl
mov ebp,eax ; indexer to line
add ebp,ebp
add ax, _cliptp
mov edi, _current_page ; point to active vga page
mov eax,[eax*4+_fastimultable] ; mul _y1 by bytes per line
add edi,eax ; di = start of line _y1
xor edx,edx
ss_more_lines:
push edi ; save right hand position
mov ax, [_poly_firstbyte+ebp]
cmp ax,_xmaxs ; check if fill done
jge ss_done
xor ebx,ebx
mov bl,steel ; use steel texture?
mov dl,pf_updown[ebx]
add dl,steelc
mov _colq,dl
inc bl
and bl,03fh ; 16 colours, 32 positions for steel texture
mov steel,bl
mov bx,[_poly_lastbyte+ebp]
add ax,_xcent
add bx,_xcent
mov edx,eax ; dx = _x1 (pixel position)
shr edx,2 ; dx/4 = bytes into line
add edi,edx ; di = addr of upper-left corner
mov ecx,ebx ; cx = _x2 (pixel position)
shr ecx,2 ; cx/4 = bytes into line
cmp edx,ecx ; start and end in same band?
jg ss_exit ; skip if _fakeline_horz fails connection
je ss_one_band_only ; if so, then special processing
mov ah,_colq ; get fill color
sub ecx,edx ; cx = # bands -1
mov esi,eax ; si = plane#(_x1)
and esi,plane_bits ; if left edge is aligned then
jz s ss_l_plane_flush ; no special processing..
; draw "left edge" of 1-3 pixels...
out_8 sc_data, _left_clip_mask[esi] ; set left edge plane mask
mov [edi], ah ; fill in left edge pixels
inc edi ; point to middle (or right) block
dec ecx ; reset cx instead of jmp ss_right
ss_l_plane_flush:
inc ecx ; add in left band to middle block
; di = addr of 1st middle pixel (band) to fill
; cx = # of bands to fill -1
ss_right:
mov esi,ebx ; get xpos2
and esi,plane_bits ; get plane values
cmp esi,0003 ; plane = 3?
je s ss_r_edge_flush ; hey, add to middle
; draw "right edge" of 1-3 pixels...
out_8 sc_data, _right_clip_mask[esi] ; right edge plane mask
mov esi,edi ; get addr of left edge
add esi,ecx ; add width-1 (bands) to point to top of right edge
dec esi
ss_right_loop:
mov [esi], ah ; fill in right edge pixels
dec ecx ; minus 1 for middle bands
jz s ss_exit ; uh.. no middle bands...
ss_r_edge_flush:
; di = addr of upper left block to fill
; cx = # of bands to fill in (width)
out_8 sc_data, all_planes ; write to all planes
mov dx, xactual/4 ; dx = di increment
sub edx, ecx ; = _screen_width-# planes filled
mov al, ah ; colour is in high and low for stosw
ss_middle_loop:
shr ecx,1 ; dont use doubleword transfer
jnc s ss_ord
stosb ; if cx odd, store byte first
ss_ord:
rep stosw
ss_exit:
pop edi
mov d [_poly_firstbyte+ebp-2],03e803e8h ; reset table for next polygon (1000 doubleword)
mov d [_poly_lastbyte+ebp-2],0fc18fc18h ; -1000 doubleword
add ebp,2
add edi,xactual/4
jmp ss_more_lines
ss_one_band_only:
cmp ax, _cliplt
jne s ss_nexit
cmp bx,ax
je s ss_exit
ss_nexit:
cmp ax, _cliprt
je s ss_exit
mov esi,eax ; get left clip mask, save _x1
and esi,plane_bits ; mask out row #
mov al,_left_clip_mask[esi] ; get left edge mask
mov esi,ebx ; get right clip mask, save _x2
and esi,plane_bits ; mask out row #
and al,_right_clip_mask[esi] ; get right edge mask byte
out_8 sc_data, al ; clip for left & right masks
mov ah,_colq ; get fill color
mov [edi], ah ; fill in pixels
jmp s ss_exit ; outa here, for this line
align 4
; small steel texture, make sure to set shl bl,*1* before ss_missub:
;pf_updown db 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
; db 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
; db 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
; db 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
; large steel texture, make sure to set shl bl,*2* before ss_missub:
pf_updown db 0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9
db 10,10,11,11,12,12,13,13,14,14,15,15
db 15,15,14,14,13,13,12,12,11,11,10,10
db 9,9,8,8,7,7,6,6,5,5,4,4,3,3,2,2,1,1,0,0
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; WN_dowindow: Fill polygon with a mesh style texture. This plots only every
; other pixel.
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
align 4
wn_done:
pop eax
wn_outearly:
mov _poly_oney,1000 ; reset for next polygon call
ret
align 4
wn_dowindow:
; out_8 sc_index, map_mask ; set up for plane select
xor eax,eax
mov ebx,_poly_oney ; ax=_y1
cmp bx,_ymins
jl s wn_missub
cmp bx,_ymaxs
jge wn_outearly
sub bx,_ymins
mov ax,bx
wn_missub:
mov ebp,eax ; indexer to line
add ebp,ebp
add ax, _cliptp
mov edi, _current_page ; point to active vga page
mov ebx,[eax*4+_fastimultable] ; mul _y1 by bytes per line
add edi,ebx ; edi = start of line _y1
xor edx,edx
and eax,1
mov al,wn_zap[eax]
mov wn_zip,al
wn_more_lines:
xor wn_zip,0fh
push edi ; save right hand position
mov ax, [_poly_firstbyte+ebp]
cmp ax,_xmaxs ; check if fill done
jge wn_done
xor ebx,ebx
mov bx,[_poly_lastbyte+ebp]
add ax,_xcent
add bx,_xcent
mov edx,eax ; dx = _x1 (pixel position)
shr edx,2 ; dx/4 = bytes into line
add edi,edx ; di = addr of upper-left corner
mov ecx,ebx ; cx = _x2 (pixel position)
shr ecx,2 ; cx/4 = bytes into line
cmp edx,ecx ; start and end in same band?
jg wn_exit ; skip if _fakeline_horz fails connection
je wn_one_band_only ; if so, then special processing
mov ah,_colq ; get fill color
sub ecx,edx ; cx = # bands -1
mov esi,eax ; si = plane#(_x1)
and esi,plane_bits ; if left edge is aligned then
jz s wn_l_plane_flush ; no special processing..
; draw "left edge" of 1-3 pixels...
mov dx,sc_data
mov al,_left_clip_mask[esi]
and al,wn_zip
out dx,al
mov [edi], ah ; fill in left edge pixels
inc edi ; point to middle (or right) block
dec ecx ; reset cx instead of jmp wn_right
wn_l_plane_flush:
inc ecx ; add in left band to middle block
; di = addr of 1st middle pixel (band) to fill
; cx = # of bands to fill -1
wn_right:
mov esi,ebx ; get xpos2
and esi,plane_bits ; get plane values
cmp esi,0003 ; plane = 3?
je s wn_r_edge_flush ; hey, add to middle
; draw "right edge" of 1-3 pixels...
mov dx,sc_data
mov al,_right_clip_mask[esi]
and al,wn_zip
out dx,al
mov esi,edi ; get addr of left edge
add esi,ecx ; add width-1 (bands) to point to top of right edge
dec esi
wn_right_loop:
mov [esi], ah ; fill in right edge pixels
dec ecx ; minus 1 for middle bands
jz s wn_exit ; uh.. no middle bands...
wn_r_edge_flush:
; di = addr of upper left block to fill
; cx = # of bands to fill in (width)
out_8 sc_data, wn_zip ; write to all planes
mov dx, xactual/4 ; dx = di increment
sub edx, ecx ; = _screen_width-# planes filled
mov al, ah ; colour is in high and low for stosw
wn_middle_loop:
shr ecx,1 ; dont use doubleword transfer
jnc s wn_ord
stosb ; if cx odd, store byte first
wn_ord:
rep stosw
wn_exit:
pop edi
mov d [_poly_firstbyte+ebp-2],03e803e8h ; reset table for next polygon (1000 doubleword)
mov d [_poly_lastbyte+ebp-2],0fc18fc18h ; -1000 doubleword
add ebp,2
add edi,xactual/4
jmp wn_more_lines
wn_one_band_only:
cmp ax, _cliplt
jne s wn_nexit
cmp bx,ax
je s wn_exit
wn_nexit:
cmp ax, _cliprt
je s wn_exit
mov esi,eax ; get left clip mask, save _x1
and esi,plane_bits ; mask out row #
mov al,_left_clip_mask[esi] ; get left edge mask
mov esi,ebx ; get right clip mask, save _x2
and esi,plane_bits ; mask out row #
and al,_right_clip_mask[esi] ; get right edge mask byte
and al,wn_zip
out_8 sc_data, al ; clip for left & right masks
mov ah,_colq ; get fill color
mov [edi], ah ; fill in pixels
jmp s wn_exit ; outa here, for this line
wn_zap db 5,0ah ; %0101,%1010
wn_zip db 0
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; DG_doglenz: Fill polygon with a glenz style vector. This routine fills
; up/down, not left/right like _polyfill. To set up the _poly_firstbyte
; and _poly_lastbyte tables for this routine, you must call _fakeline_vert.
; Do not use _fakeline_horz, as _fakeline_horz fills left/right.
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
dg_doglenz:
xor esi,esi
xor eax,eax
mov ebx,_poly_oney ; ax=_x1
cmp bx,_xmins
jl s dg_missub
cmp bx,_xmaxs
jge wn_outearly
sub bx,_xmins
mov ax,bx
dg_missub:
mov ebp,eax ; indexer to line
add ebp,ebp
add ax, _cliplt
mov ebx,eax
; out_8 sc_index,map_mask
out_8 gc_index,read_map
dg_mnloop:
mov ax, [_poly_firstbyte+ebp]
cmp ax, _ymaxs
jg s dg_doneall
mov si, [_poly_lastbyte+ebp]
sub si,ax
jz s dg_doneline
inc ax
mov edi, _current_page ; point to active vga page
add ax,_ycent
movzx eax,ax
add edi,[eax*4+_fastimultable] ; mul _y1 by bytes per line
mov ecx,ebx ; si = -len, bx = start, edi = screen (left)
mov eax,ebx
shr eax,2
add edi,eax
mov al, 1 ; map mask & plane select register
and cl, plane_bits ; get plane bits
shl al, cl ; get plane select value
out_8 sc_data, al ; select plane
mov al, cl
out_8 gc_index+1, al
xor ecx,ecx
mov cl,_colq
mov ecx,[_xreftable+ecx*4]
xor eax,eax
dg_mainloop:
mov al,[edi]
mov al,[ecx+eax]
mov [edi],al
add edi,xactual/4
dec esi
jnz s dg_mainloop
dg_doneline:
mov d [_poly_firstbyte+ebp-2],03e803e8h ; reset table for next polygon (1000 doubleword)
mov d [_poly_lastbyte+ebp-2],0fc18fc18h ; -1000 doubleword
add ebp,2
inc ebx
jmp dg_mnloop
dg_doneall:
mov _poly_oney,1000
mov leftmost,1000
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; DS_dostone: Fill polygon with a stone texture. Fill is performed
; up/down, not left/right like _polyfill. To set up the _poly_firstbyte
; and _poly_lastbyte tables for this routine, you must call _fakeline_vert.
; Do not use _fakeline_horz, as _fakeline_horz fills left/right.
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
ds_dostone:
xor esi,esi
xor eax,eax
mov ebx,_poly_oney ; ax=_x1
cmp bx,_xmins
jl s ds_missub
cmp bx,_xmaxs
jge wn_outearly
sub bx,_xmins
mov ax,bx
ds_missub:
mov ebp,eax ; indexer to line
add ebp,ebp
add ax, _cliplt
mov ebx,eax
xor ecx,ecx
mov cl,_colq
mov al,[_stoneadd+ecx]
mov _colq,al
mov ecx,[_stonetbl+ecx*4]
mov edx,[ecx]
add edx,ecx
add ecx,[ecx+4]
mov ds_ggh,edx
mov eax,_poly_oney
sub ax,_xmins
jnl s ds_nol
neg eax
cmp ax,_cliplt
jbe ds_llk
mov ax,_cliplt
ds_llk:
add ecx,eax
ds_nol:
xor eax,eax
mov ax,_cliplt
add ecx,eax
mov ds_yvar,ecx
mov ax,leftmost
add ax,_ycent
jnl s ds_mnloop2
xor eax,eax
ds_mnloop2:
sub ds_ggh,eax
ds_mnloop:
mov dx, [_poly_firstbyte+ebp]
cmp dx, _ymaxs
jg ds_doneall
mov si, [_poly_lastbyte+ebp]
sub si,dx
jle s ds_doneline
inc dx
mov edi, _current_page ; point to active vga page
add dx,_ycent
movzx edx,dx
add edi,[edx*4+_fastimultable] ; mul _y1 by bytes per line
mov ecx,ebx ; si = -len, bx = start, edi = screen (left)
mov eax,ebx
shr eax,2
add edi,eax
mov al, 1 ; map mask & plane select register
and cl, plane_bits ; get plane bits
shl al, cl ; get plane select value
mov ecx,edx
out_8 sc_data, al ; select plane
mov eax,ds_yvar
movzx eax,byte ptr [eax]
add ecx,eax
add ecx,ds_ggh
mov dl,_colq
ds_mainloop:
mov al,[ecx] ; the stone copy loop!
add al,dl
mov [edi],al
add edi,xactual/4
inc ecx
dec esi
jnz s ds_mainloop
ds_doneline:
mov d [_poly_firstbyte+ebp-2],03e803e8h ; reset table for next polygon (1000 doubleword)
mov d [_poly_lastbyte+ebp-2],0fc18fc18h ; -1000 doubleword
add ebp,2
inc ebx
inc ds_yvar
jmp ds_mnloop
ds_doneall:
mov _poly_oney,1000
mov leftmost,1000
ret
ds_ggh dd 0
ds_yvar dd 0
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;
; Table of values for fast multiplication by screen width
; eg mov eax,[esi*4+_fastimultable] ; eax = esi*320
;
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_fastimultable label dword
i=0
rept yactual
dd i*(xactual/4)
i=i+1
endm
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;
; Hey! where is my postcard! see readme.doc file and send me that postcard!
;
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;
; _fakeline_horz: Draw a line in tables _poly_firstbyte,_poly_lastbyte, adjust _poly_oney if neccessary
;
; In:
; Regs=none
; Memory:
; _x1 - x of line - cartisian format
; _y1 - y of line
; _x2 - x of line
; _y2 - y of line
;
; Out:
; Regs=none
;
; Notes:
;
; Line is not drawn on screen but is drawn in memory tables. To use,
; tables must be clear, (default is always clear), just draw
; line around screen, in any order, then call _polyfill. The polygon will
; be drawn and checked in memory, then _polyfill will plop it on the current
; page. _polyfill routine clears tables during plot so tables are ready for
; more lines and more polygons.
;
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
align 4
_fakeline_horz:
mov ax,_y1
cmp _y2,ax ; flip order of points if drawing up
jg s okorder
mov bx,_x1
xchg bx,_x2
xchg bx,_x1
xchg ax,_y2
mov _y1,ax
okorder:
movsx eax,ax
cmp eax,_poly_oney
jge s nonew_poly_oney
mov _poly_oney,eax
nonew_poly_oney:
mov ax,_x2 ; ax=x
sub ax,_x1
mov bx,_y2 ; bx=y
sub bx,_y1
jle sliver
mov rise,bx
movsx ebx,bx
shl eax,16
cdq
idiv ebx
mov ebp,eax ; ebp = slope*65536 (allows decimals)
mov ax,_ymins
cmp _y1,ax ; check if above screen
jge s li_abov1
sub ax,_y1 ; ax = abs(difference of ymin-_y1)
sub rise,ax ; dec counter
jle li_out ; line totally off screen
movsx eax,ax ; prepare for 32bit mul
imul ebp
shr eax,16 ; get top word
add _x1,ax ; set new _x1,_y1 pair
mov ax,_ymins
mov _y1,ax
li_abov1:
movsx edx,_x1
shl edx,16
mov cx,rise
mov ax,_y1
movzx ebx,ax ; bx pointer first/_poly_lastbyte table
sub bx,_ymins
add ebx,ebx ; bx now word
add eax,ecx ; will line go off bottom of screen?
cmp ax,_ymaxs
jl s linep ; no...
sub ax,_ymaxs ; yes, truncate cx for early exit
sub cx,ax
jle s li_out ; right off screen
linep:
mov eax,edx
mov di,_xmins
mov si,_xmaxs1
and ecx,0000ffffh
align 4
lineloopclip:
shr edx,16 ; main line drawing loop (clipped)
cmp dx,di
jnge s nou
cmp dx,si
jnle s noqq
noq:
cmp dx,_poly_firstbyte[ebx] ; fix first and _poly_lastbyte table
jge s ci1
mov _poly_firstbyte[ebx],dx
ci1:
cmp dx,_poly_lastbyte[ebx]
jng s ci2
mov _poly_lastbyte[ebx],dx
ci2:
add eax,ebp
mov edx,eax
add ebx,2
dec ecx
jnz s lineloopclip
li_out:
ret
nou:
mov dx,di
jmp s noq
noqq:
mov dx,si
jmp s noq
align 4
sliver:
movzx ebx,_y1 ; bx pointer first/_poly_lastbyte table
cmp bx,_ymaxs
jge li_out
cmp bx,_ymins ; clip to borders
jl li_out
sub bx,_ymins
add ebx,ebx ; ebx now word
mov cx,_x1
cmp cx,_xmins
jge s nouq1
mov cx,_xmins
nouq1:
cmp cx,_xmaxs
jl s noqq1
mov cx,_xmaxs1
noqq1:
cmp cx,_poly_firstbyte[ebx] ; fix first and _poly_lastbyte table
jg s ci1q1
mov _poly_firstbyte[ebx],cx
ci1q1:
cmp cx,_poly_lastbyte[ebx]
jng s ci6q1
mov _poly_lastbyte[ebx],cx
ci6q1:
mov cx,_x2
cmp cx,_xmins
jge s nouq2
mov cx,_xmins
nouq2:
cmp cx,_xmaxs
jl s noqq2
mov cx,_xmaxs1
noqq2:
cmp cx,_poly_firstbyte[ebx] ; fix first and _poly_lastbyte table
jg s ci1q2
mov _poly_firstbyte[ebx],cx
ci1q2:
cmp cx,_poly_lastbyte[ebx]
jng s ci6q
mov _poly_lastbyte[ebx],cx
ci6q:
ret
align 4
_fakeline_vert:
mov ax,_x2
mov bx,_y2
cmp bx,leftmost
jg fg_not1
mov leftmost,bx
fg_not1:
xchg _y1,ax
xchg _x1,bx
cmp ax,leftmost
jg fg_not2
mov leftmost,ax
fg_not2:
mov _x2,ax
mov _y2,bx
mov ax,_y1
cmp _y2,ax ; flip order of points if drawing up
jg s okorderg
mov bx,_x1
xchg bx,_x2
xchg bx,_x1
xchg ax,_y2
mov _y1,ax
okorderg:
movsx eax,ax
cmp eax,_poly_oney
jge s nonew_poly_oneyg
mov _poly_oney,eax
nonew_poly_oneyg:
mov ax,_x2 ; ax=x
sub ax,_x1
mov bx,_y2 ; bx=y
sub bx,_y1
jle sliverg
mov rise,bx
movsx ebx,bx
shl eax,16
cdq
idiv ebx
mov ebp,eax ; ebp = slope*65536 (allows decimals)
mov ax,_xmins
cmp _y1,ax ; check if above screen
jge s li_abov1g
sub ax,_y1 ; ax = abs(difference of ymin-_y1)
sub rise,ax ; dec counter
jle li_outg ; line totally off screen
movsx eax,ax ; prepare for 32bit mul
imul ebp
shr eax,16 ; get top word
add _x1,ax ; set new _x1,_y1 pair
mov ax,_xmins
mov _y1,ax
li_abov1g:
movsx edx,_x1
shl edx,16
mov cx,rise
mov ax,_y1
movzx ebx,ax ; bx pointer first/_poly_lastbyte table
sub bx,_xmins
add ebx,ebx ; bx now word
add eax,ecx ; will line go off bottom of screen?
cmp ax,_xmaxs
jl s linepg ; no...
sub ax,_xmaxs ; yes, truncate cx for early exit
sub cx,ax
jle s li_outg ; right off screen
linepg:
mov eax,edx
mov di,_ymins1
mov si,_ymaxs1
and ecx,0000ffffh
align 4
lineloopg:
shr edx,16 ; main line drawing loop!!!
cmp dx,di
jg s noug
mov dx,di
jmp s noqg
noug:
cmp dx,si
jl s noqg
mov dx,si
noqg:
cmp dx,_poly_firstbyte[ebx] ; fix first and _poly_lastbyte table
jge s ci1g
mov _poly_firstbyte[ebx],dx
ci1g:
cmp dx,_poly_lastbyte[ebx]
jng s ci2g
mov _poly_lastbyte[ebx],dx
ci2g:
add eax,ebp
mov edx,eax
add ebx,2
dec ecx
jnz s lineloopg
li_outg:
ret
align 4
sliverg: ret
movzx ebx,_y1 ; bx pointer first/_poly_lastbyte table
cmp bx,_xmaxs
jge li_outg
cmp bx,_xmins ; clip to borders
jl li_outg
sub bx,_ymins
add ebx,ebx ; ebx now word
mov cx,_x1
cmp cx,_ymins
jge s nouq1g
mov cx,_ymins
nouq1g:
cmp cx,_ymaxs
jl s noqq1g
mov cx,_ymaxs1
noqq1g:
cmp cx,_poly_firstbyte[ebx] ; fix first and _poly_lastbyte table
jg s ci1q1g
mov _poly_firstbyte[ebx],cx
ci1q1g:
cmp cx,_poly_lastbyte[ebx]
jng s ci6q1g
mov _poly_lastbyte[ebx],cx
ci6q1g:
mov cx,_x2
cmp cx,_ymins
jge s nouq2g
mov cx,_ymins
nouq2g:
cmp cx,_ymaxs
jl s noqq2g
mov cx,_ymaxs1
noqq2g:
cmp cx,_poly_firstbyte[ebx] ; fix first and _poly_lastbyte table
jg s ci1q2g
mov _poly_firstbyte[ebx],cx
ci1q2g:
cmp cx,_poly_lastbyte[ebx]
jng s ci6qg
mov _poly_lastbyte[ebx],cx
ci6qg:
ret
db " **** Hey, What are you doing ripping my code?! **** "
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;
; _set_clip_absolute: Set clipping parameters - non cartisian
;
; In:
; AX - left for clip
; BX - top for clip
; CX - right for clip
; DX - bottom for clip
; Out:
; ?
;
; Notes:
; Set new clipping parameters where center is in middle of points ax,bx cx,dx
; where points are absolutes! eg (10,10) (50,50) would be a small window in
; the top corner of the screen.
;
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_set_clip_absolute:
mov si,cx ; calc center based on points
sub si,ax
shr si,1
add si,ax
mov di,dx
sub di,bx
shr di,1
add di,bx
sub ax,si ; now make points offset from center
sub cx,si
sub bx,di
sub dx,di ; fall through to _set_clip_offset
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;
; _set_clip_offset: Set clipping parameters - cartisian
;
; In:
; AX - left for clip - in cartisian format
; BX - top for clip
; CX - right for clip
; DX - bottom for clip
; SI - x of screen center - in cartisian format
; DI - y of screen center
; Out:
; ?
;
; Notes:
;
; Set new clipping parameters. does all pre-calculation for variables and
; resets _poly_oney, _poly_firstbyte and _poly_lastbyte table. SI,DI is center of screen. AX,BX
; and CX,DX are topleft and botright points to clip to. clipping will include
; minimum clip variables but will exclude maximum clip variables. eg -160,-100
; +160,+100, with center 160,100 are valid clip parameters. points are offsets
; from center, not absolutes! this allows you to have the camera looking to the
; left or right of where the pilot/plane is moving without having to change
; the camera angle. Note: this can only change slightly as distortion occures
; with too large an offset. Make sure to assemble the original file with the
; maximum Y size you will ever need so tables are set to correct size. You can
; never increase the total screen Y clipping beyond the original assembley
; restraints, but you can create any sized smaller windows.
;
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_set_clip_offset:
mov bp,dx
sub bp,bx
cmp bp,ymax-ymin ; check input parameters with assembley restraints
jg you_must_assemble_original_file_with_larger_clipping_parameters_to_achieve_this
mov _xmins,ax
mov _xmaxs,cx
mov _ymins,bx
mov _ymaxs,dx
mov _xcent,si
mov _ycent,di
mov _cliptp,di
add _cliptp,bx
mov _ycentp1,di
inc _ycentp1
mov _ycents1,di
dec _ycents1
mov _clipbt,di
add _clipbt,dx
dec _clipbt
mov _cliplt,si
add _cliplt,ax
mov _cliprt,si
add _cliprt,cx
dec _cliprt
mov xmaxxcent,si
add xmaxxcent,cx
mov ymaxycent,di
add ymaxycent,dx
mov _xmins1,ax
dec _xmins1
mov _xmaxs1,cx
dec _xmaxs1
mov _ymins1,bx
dec _ymins1
mov _ymaxs1,dx
dec _ymaxs1
movsx eax,ax
movsx ebx,bx
movsx ecx,cx
movsx edx,dx
mov xmit,eax
mov xmat,ecx
mov ymit,ebx
mov ymat,edx
sub xmit,tolerance
add xmat,tolerance
sub ymit,tolerance
add ymat,tolerance
you_must_assemble_original_file_with_larger_clipping_parameters_to_achieve_this:
ret
align 4
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; _drawvect: Draw vectors from sides list.
; In=Out=null
;
; Notes:
; Number of "sides" is "_showing". Commands are in "textures" lists. All
; of this is set up by Load_points and Loadsides routines.
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
dv_none2:
ret
_drawvect:
cmp _showing,0 ; no sides visible?
je s dv_none2
mov whichside,0 ; start at side 0
mov ebp,order[0] ; indexer to sides
dv_loop2:
test textures[ebp],line+himap+point+texture+glenz ; test if line, point, scalable bitmap or bitmapped texture
jnz dv_testit ; yes, do other routine
mov polytype,offset _fakeline_horz
dv_contq:
shl ebp,mult
mov dx,sides[ebp] ; first point is end flag
mov fex,dx
dv_loop1:
movzx esi,sides[ebp] ; get point, shl 1 not needed, pre-shl'ed
mov eax,[xp+esi]
mov ebx,[yp+esi]
mov _x1,ax
mov _y1,bx
mov si,[sides+ebp+2] ; get next point
cmp si,fex ; test if last = first, therefore done
pushf
mov eax,[xp+esi]
mov ebx,[yp+esi]
mov _x2,ax
mov _y2,bx
push ebp
call [polytype] ; draw next line
pop ebp
add ebp,2 ; bump to next pointer now
popf ; was this point equal to the first point?
jne s dv_loop1 ; no, draw more lines
mov esi,whichside ; set colour for this side
mov esi,order[esi]
mov al,b surfcolors[esi]
mov _colq,al
xor ecx,ecx
mov cl,byte ptr textures[esi+1] ; use register which we can access low byte
and cl,7
call [polyjumps+ecx*4]
dv_return:
add whichside,4 ; bump bp to next block of points
mov ebp,whichside
mov ebp,order[ebp] ; get sort order
dec _showing ; count for all sides
jne dv_loop2
dv_none:
ret
polyjumps dd offset _polyfill ; 0 ; solid fill
dd offset wn_dowindow ; 256 ; mesh
dd offset ss_dosteel ; 512 ; sine wave
dd offset 0 ; 512+256
dd offset dg_doglenz ; 1024 ; glenz vector
dd offset ds_dostone ; 1024+256 ; stone texture
dd offset 0 ; 1024+512
dd offset 0 ; 1024+512+256
dv_assinez:
mov polytype,offset _fakeline_vert
jmp dv_contq
align 4
dv_testit:
mov ax,textures[ebp] ; perform command, return to dv_return
test eax,glenz
jnz dv_assinez
test eax,line
jnz dv_doline
test eax,point
jnz dv_dopoint
test eax,texture
jnz dv_texture
; draw bitmap at location x,y,z
shl ebp,mult
push eax ebp
movzx ebx,w [sides+4+ebp]
movzx ecx,w [sides+6+ebp]
movzx esi,[sides+2+ebp]
shl esi,2 ; si = dword
add ebx,_bitx[esi]
add ecx,_bity[esi] ; ebx,ecx = top corner of _bitmap in 3d
mov eax,_bitbase[esi]
mov _bitmap,eax
mov si,[sides+0+ebp]
mov ebp,[zp+esi]
call _make3d ; ebx,ecx = difference from center
pop ebp
movzx esi,[sides+0+ebp] ; get point
mov eax,[xp+esi]
mov ebp,[yp+esi]
sub ax,bx ; bx = x width/2 ax, bp = top corner
sub bp,cx ; cx = y height/2
add ax,_xcent
add bp,_ycent
mov _scale_destx,ax
mov _scale_desty,bp
add bx,bx
add cx,cx
mov _scale_destwidth,bx
mov _scale_destheight,cx
pop eax
test al,lomap-himap ; test to use 1/4 scale _bitmap or full scale
jz s noq19
call _xscale4
jmp dv_return
align 4
noq19:
call _xscale2
noq7:
jmp dv_return
align 4
dv_dopoint:
mov dx,surfcolors[ebp] ; get colour of point
shl ebp,mult
movzx esi,[sides+ebp] ; get point x,y
mov ebx,[xp+esi]
mov ecx,[yp+esi]
cmp bx,_xmins ; check if on screen
jl s noq7
cmp bx,_xmaxs
jge s noq7
cmp cx,_ymins
jl s noq7
cmp cx,_ymaxs ; _ymaxs1 if larger pixel
jge s noq7
mov edi, _current_page ; point to active vga page
add bx,_xcent
add cx,_ycent
mov bp,dx ; save colour
mov si,cx
mov eax,[esi*4+_fastimultable] ; get offset to start of line
mov cx, bx ; copy to extract plane # from
shr bx, 2 ; x offset (bytes) = xpos/4
add bx, ax ; offset = width*ypos + xpos/4
mov ax, map_mask_plane1 ; map mask & plane select register
and cl, plane_bits ; get plane bits
shl ah, cl ; get plane select value
out_16 sc_index, ax ; select plane
and ebx,0000ffffh
mov ax,bp ; re-get colour
mov [edi+ebx],al ; draw pixel, low is top, high is bottom
; add edi,xactual/4
; mov [edi+ebx],ah ; draw larger bullet/pixel (high byte)
; if drawing larger pixel, change above code to this!
; cmp cx,_ymaxs1
; jge s noa7
jmp dv_return
align 4
; handle line command from _drawvect, uses _clipped_line routine
dv_doline:
mov edi,ebp ; save...
mov bp,surfcolors[ebp]
shl edi,mult
movzx esi,[sides+edi] ; get first point
mov edx,[xp+esi]
mov ecx,[yp+esi]
mov si,[sides+edi+2] ; second point indexer
mov eax,[xp+esi] ; now load up second point
mov ebx,[yp+esi]
call _clipped_line
jmp dv_return ; return to _drawvect
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; _clipped_line: Draw clipped line in cartesian format from (dx,cx) to (ax,bx)
; using colour bp
; In:
; AX - _x2
; BX - _y2
; CX - _y1
; DX - _x1
; BP - Colour
; _current_page - current screen start location
; Out:null
;
; Similar routine to _fakeline_horz but faster, more accurate and draws directly
; to screen (_current_page). Routine updates clearing borders (if used)
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_clipped_line:
cmp bx,cx ; flip order of points if drawing up
jg s r_okorder
xchg bx,cx
xchg ax,dx
r_okorder:
mov _x1,dx
mov _y1,cx
mov _x2,ax
mov _y2,bx
sub ax,dx
sub bx,cx
mov dx,bp
mov _colq,dl
mov dx,_ymaxs
cmp _y1,dx
jge cl_return
mov rise,bx
movsx ebx,bx
or ebx,ebx
jne s r_nsliver
mov bx, _y1
cmp bx, _ymins ; draw sliver, avoid divide by zero
jl cl_return
cmp bx, dx ; dx = ymax
jge cl_return
add bx,_ycent
movzx esi,bx
mov eax,[esi*4+_fastimultable] ; get offset to start of line
mov edi, _current_page
add edi, eax ; edi = starting y location
mov rise,1
mov dx, _x1 ; from here...
mov si, _x2 ; ..to here
cmp si,_xmins
jge s u_nou3
mov si,_xmins
u_nou3:
cmp si,_xmaxs
jl s u_noq3
mov si,_xmaxs1
u_noq3:
jmp r_splint ; re-enter draw later in code
align 4
r_nsliver:
shl eax,16
cdq
idiv ebx
mov ebp,eax ; ebp = slope*65536 (allows decimals)
mov ax,_ymins
cmp _y1,ax ; check if above screen
jge s r_li_abov1
sub ax,_y1 ; ax = abs(difference of ymin-_y1)
sub rise,ax ; dec counter
jle cl_return ; line totally off screen
movsx eax,ax ; prepare for 32bit mul
imul ebp
shr eax,16 ; get top word
add _x1,ax ; set new _x1,_y1 pair
mov ax,_ymins
mov _y1,ax
r_li_abov1:
mov bx,_y1 ; bx distance from top of screen
add bx,_ycent
movzx esi,bx ; calculate screen address
mov eax,[esi*4+_fastimultable] ; get offset to start of line
mov edi, _current_page
add edi,eax ; edi = starting y location
movsx edx,_x1
shl edx,16
mov cx,rise
mov ax,_y1
add ax,cx ; will line go off bottom of screen?
cmp ax,_ymaxs
jl s r_linep ; no...
sub ax,_ymaxs ; yes, truncate cx for early exit
sub rise,ax
jle cl_return
r_linep:
mov eax,edx
and ecx,0000ffffh
mov esi,edx
shr esi,16
cmp si,_xmins
jge s r_nou
mov si,_xmins
r_nou:
cmp si,_xmaxs
jl s r_noq
mov si,_xmaxs1
align 4
r_noq:
r_lineloop:
add eax,ebp ; main line drawing loop!!! (for lines)
mov edx,eax
shr edx,16
r_splint:
cmp dx,_xmins
jge s u_nou
mov dx,_xmins
cmp dx,si
je r_mis
u_nou:
cmp dx,_xmaxs
jl s u_noq
mov dx,_xmaxs1
cmp dx,si
je r_mis
u_noq:
push edx edi ebp eax ; save for next line
cmp dx,si
jle s r_no_switch
xchg dx,si
r_no_switch:
add dx,_xcent
add si,_xcent
mov ax,dx
mov bx,si
mov _x2,si
movzx edx,dx
shr edx,2 ; dx/4 = bytes into line
add edi,edx ; di = addr of upper-left corner
movzx ecx,bx ; cx = _x2 (pixel position)
shr ecx,2 ; cx/4 = bytes into line
cmp dx,cx ; start and end in same band?
je rf_one_band_only ; if so, then special processing
sub cx,dx ; cx = # bands -1
mov esi,eax ; si = plane#(_x1)
and esi,plane_bits ; if left edge is aligned then
jz s rf_l_plane_flush ; no special processing..
; draw "left edge" of 1-3 pixels...
out_8 sc_data, _left_clip_mask[esi] ; set left edge plane mask
mov al,_colq ; get fill color
mov [edi], al ; fill in left edge pixels
inc edi ; point to middle (or right) block
dec ecx ; reset cx instead of jmp s rf_right
rf_l_plane_flush:
inc ecx ; add in left band to middle block
; di = addr of 1st middle pixel (band) to fill
; cx = # of bands to fill -1
rf_right:
mov esi,ebx ; get xpos2
and esi,plane_bits ; get plane values
cmp esi,0003 ; plane = 3?
je s rf_r_edge_flush ; hey, add to middle
; draw "right edge" of 1-3 pixels...
out_8 sc_data, _right_clip_mask[esi] ; right edge plane mask
mov esi,edi ; get addr of left edge
add esi,ecx ; add width-1 (bands) to point to top of right edge
dec esi
mov al,_colq ; get fill color
rf_right_loop:
mov [esi], al ; fill in right edge pixels
dec ecx ; minus 1 for middle bands
jz rf_exit ; uh.. no middle bands...
rf_r_edge_flush:
; di = addr of upper left block to fill
; cx = # of bands to fill in (width)
out_8 sc_data, all_planes ; write to all planes
mov edx, xactual/4 ; dx = di increment
sub edx, ecx ; = _screen_width-# planes filled
mov al, _colq ; get fill color
mov ah, al ; colour is in high and low for stosw
push ax ; make colour 32 bit
shl eax,16
pop ax
rf_middle_loop:
shr ecx,1 ; use doubleword transfer
jnc s rf_ord
stosb ; if cx odd, store byte first
rf_ord:
rep stosw
jmp s rf_exit ; outa here, for this line
rf_one_band_only:
mov esi,eax ; get left clip mask, save _x1
and esi,plane_bits ; mask out row #
mov al,_left_clip_mask[esi] ; get left edge mask
mov esi,ebx ; get right clip mask, save _x2
and esi,plane_bits ; mask out row #
and al,_right_clip_mask[esi] ; get right edge mask byte
out_8 sc_data, al ; clip for left & right masks
mov al, _colq ; get fill color
mov [edi], al ; fill in pixels
rf_exit:
pop eax ebp edi esi ; pop screen left address
r_mis:
add edi, xactual/4
dec rise
jg r_lineloop
cl_return:
ret
align 4
dv_texture:
;movzx ebx,surfcolors[ebp]
;mov eax,_bitbase[ebx*4]
;mov _scaled_texture_bitmap_offset,eax
;
;shl ebp,mult
;
;mov bx,[sides+0+ebp]
;mov ax,xp[ebx]
;mov bx,yp[ebx]
;mov _tex_xorg+0,ax
;mov _tex_yorg+0,bx
;
;mov bx,[sides+2+ebp]
;mov ax,xp[ebx]
;mov bx,yp[ebx]
;mov _tex_xorg+2,ax
;mov _tex_yorg+2,bx
;
;mov bx,[sides+4+ebp]
;mov ax,xp[ebx]
;mov bx,yp[ebx]
;mov _tex_xorg+4,ax
;mov _tex_yorg+4,bx
;
;mov bx,[sides+6+ebp]
;mov ax,xp[ebx]
;mov bx,yp[ebx]
;mov _tex_xorg+6,ax
;mov _tex_yorg+6,bx
;
;call _tex_drawtexturemap ; not implemented yet!
jmp dv_return
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; _sortlist: Bubble sort for sides
; In=Out=null
;
; Sort is not perfect since many sides can use the same point.
; If this point is the first point in the list and therefore zeds[] uses
; the same point for sort, the routine may mess up when plotting at some
; acute angles. If you ever notice this, you are way too picky. You
; could fix this by adjusting the load_sides routine to search for the
; closest z point.
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
align 4
_sortlist dd o shell_sort ; offset to requested sort type
minusd equ offset zeds - offset order
shell_sort:
mov ebx,_showing
align 4
mainwhile:
shr ebx,1
mov ebp,ebx
shl ebp,2
align 4
while_inner:
xor edx,edx
mov esi,o zeds
mov ecx,_showing
sub ecx,ebx
align 4
forloop: mov eax,[esi]
cmp [esi+ebp],eax
jle nextfor
xchg eax,[esi+ebp]
mov [esi],eax
mov eax,[esi - minusd]
xchg eax,[esi - minusd + ebp]
mov [esi - minusd],eax
mov edx,1
align 4
nextfor: add esi,4
loop forloop
cmp edx,1
je while_inner
cmp ebx,1
jne mainwhile
ret
align 4
bubble_sort:
xor edx,edx
mov esi,o zeds
mov ecx,_showing
dec ecx
align 4
bforloop:mov eax,[esi]
cmp [esi+4],eax
jle bnextfor
xchg eax,[esi+4]
mov [esi],eax
mov eax,[esi - minusd]
xchg eax,[esi - minusd + 4]
mov [esi - minusd],eax
mov edx,1
align 4
bnextfor:add esi,4
loop bforloop
cmp edx,1
je bubble_sort
ret
selection_sort:
mov esi,_showing
cmp esi,3 ; if only one surface, exit
jbe qke
shl esi,2 ; esi = dword
add esi,o order
align 4
nextcx:
sub esi,4 ; point to last word in order[] table
mov ebp,esi ; set order pointer
mov ebx,d [esi] ; get order[si]
mov edi,esi
add edi,minusd
mov ecx,d [edi] ; get zeds[si]
align 4
nextdx:
sub edi,4
sub ebp,4
cmp ecx,d [edi] ; zeds is point from side, should be max z
jle s donothing
xchg ecx,d [edi] ; don't flip entire side, just indexers to it
xchg ebx,d [ebp]
donothing:
cmp ebp,o order ; check bp = 0
jne s nextdx
mov [esi + minusd],ecx
mov [esi],ebx
cmp esi,o order + 4
jne s nextcx
qke:
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
; Copy real objects to virtual objects. You MUST call this routine before
; you draw your objects or they will be in the same place as last time.
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_copy_virtual_objects:
mov edi,o v_whatshape
mov esi,o _whatshape
mov ecx,((2+2+2+4+4+4+2+2+2+1+1+1)*(maxobjects+1)+4)/4
rep movsd
ret